<template>
  <div class="login">
    <div class="loginForm">
      <div class="form">
        <el-form
          :model="loginForm"
          status-icon
          :rules="rules"
          ref="loginFormRef"
          label-width="70px"
          class="login-container"
          label-position="left"
          @keyup.enter="handleLogin(loginFormRef)"
        >
          <h3 class="login_title">智能汽车Mes管理平台</h3>
          <el-form-item class="item" label="账户名" prop="username">
            <el-input id="username" name="username" v-model="loginForm.username" prefix-icon="UserFilled" autocomplete="off"></el-input>
          </el-form-item>
          <el-form-item label="密码" prop="password">
            <el-input id="password" name="password" show-password v-model="loginForm.password" prefix-icon="Lock" autocomplete="off"></el-input>
          </el-form-item>
          <el-form-item label="验证码" prop="verifyCode">
            <!-- 这里加入div是为了通过容器实现验证码文本框和验证码图片的两端对齐 -->
            <div style="width: 100%; display: flex; justify-content: space-between">
              <el-input v-model="loginForm.verifyCode" autocomplete="off" style="width: 110px" placeholder="请输入验证码"></el-input>
              <el-image :src="codeAction" v-loading="tokenLoading" style="height: 32px" @click="getCode">
                <!--只能同时有一个插槽生效
              <template #placeholder>
                  <div class="image-slot">
                    <el-icon><Refresh />加载中……</el-icon>
                  </div>
                </template> -->
                <!--如果加载失败，则el-image中的点击事件将无法再使用，需要在error插槽中再加入点击事件-->
                <template #error>
                  <div class="el-image-error-slot" @click="getCode">
                    <el-icon><Picture /></el-icon>
                  </div>
                </template>
              </el-image>
              <!--          <img :src="imgSrc" style="height:32px;margin-left:10px;"/>-->
            </div>
          </el-form-item>
          <el-form-item>
            <el-button id="login-button" name="login-button" type="primary" @click="handleLogin(loginFormRef)" :loading="loadingButton"
              >登陆</el-button
            >
            <!--          <el-icon><user /></el-icon>
                        <el-icon><user-filled /></el-icon>
                        <el-icon><apple /></el-icon>
                        <edit style="width: 1em; height: 1em; margin-right: 8px;" />-->
            <!--          <el-button type="primary" icon="Edit" circle></el-button>-->
          </el-form-item>
        </el-form>
      </div>
      <img src="../assets/image/loginFormBg.png" alt="" />
    </div>
  </div>
</template>
<script lang="ts" setup>
import { reactive, ref, onMounted } from 'vue';
import { ElForm, ElMessage } from 'element-plus';
import type { FormInstance, FormRules } from 'element-plus';
import { useRouter } from 'vue-router';
import { useAuthStore } from '@/stores/auth';
import { getVerifyCode, login } from '@/api/mes/login';
import type { ResponseData } from '@/types/interface/base_interface';
// 导入路由
const router = useRouter(); // 创建路由对象
const authStore = useAuthStore();

// const imgSrc = computed(() => `${process.env.BASE_URL}a.jpg`);
// console.log(imgSrc);

// 1.验证码模块
let token = ''; // 用于验证码的token
let tokenLoading = ref<boolean>(false); // 图片的加载验证码
// 验证码的访问地址
const codeAction = ref<string>();
// 变更验证码
const getCode = async () => {
  tokenLoading.value = true; // 在加载中
  // 加上随机数，让图片的缓存失效，否则验证码图片会不变。后改为base64位格式，此代码留存
  // codeAction.value = `${proxy.$urls.API_URL_BACKSTAGE_VERIFYCODE}?random=${new Date().getMilliseconds()}`;
  const responseData: ResponseData = await getVerifyCode(token);
  tokenLoading.value = false; // 结束加载
  //如果接口返回数据，也是为了避免网络等错误导致没有数据返回。也可以用try...catch来处理
  if (responseData) {
    token = responseData.data.token; // 获取token
    if (typeof responseData.data.virifyCode !== 'undefined' || responseData.data.virifyCode != null) {
      loginForm.verifyCode = responseData.data.virifyCode; //验证码，这里仅用于测试的时候自动填充验证码，正式运行时必须取消
    }
    codeAction.value = `data:image/png;base64,${responseData.data.img}`; //  接收为base64的图片要在头部加上data:image/png;base64,
  }
};
// 初始化生成验证码
onMounted(async () => {
  await getCode();
});

//2.登录验证
// 登录表单对象
const loginForm = reactive({
  username: 'lcvc_admin',
  password: 'lcvc123456',
  verifyCode: ''
});
let loadingButton = ref(false); // 登录按钮加载状态

// 表单验证规则
const rules = reactive<FormRules>({
  username: [
    { required: true, message: '请输入账户名', trigger: 'blur' },
    {
      min: 3,
      max: 20,
      message: '账户名长度必须在3-20个字符之间',
      trigger: 'blur'
    }
  ],
  password: [
    { required: true, message: '请输入密码', trigger: 'blur' },
    {
      min: 6,
      max: 12,
      message: '密码长度必须在6-12个字符之间',
      trigger: 'blur'
    }
  ],
  verifyCode: [{ required: true, message: '请输入验证码', trigger: 'blur' }]
});
// 定义登录表单的对象
const loginFormRef = ref<FormInstance>();
const handleLogin = (formEl: FormInstance | undefined) => {
  if (!formEl) return;
  formEl.validate((valid, fields) => {
    if (valid) {
      // 如果验证通过
      loadingButton.value = true;
      login(loginForm.username, loginForm.password, loginForm.verifyCode, token)
        .then((resData: any) => {
          // 操作成功
          loadingButton.value = false;
          if (resData.success) {
            // 如果登录成功
            // 登录成功提示
            ElMessage.success('登录成功');
            // 在Store中处理登录成功后的业务
            authStore.handleLoginSuccess(resData);
            router.push('/backstage');
          } else {
            //如果登录失败
            // 登录失败可能会刷新验证码，但验证码错误不会
            if (resData.data !== '') {
              // 如果错误并传递了数据，说明有验证码信息
              token = resData.data.token; // 获取token
              if (typeof resData.data.virifyCode !== 'undefined' || resData.data.virifyCode != null) {
                loginForm.verifyCode = resData.data.virifyCode; //验证码，这里仅用于测试的时候自动填充验证码，正式运行时必须取消
              }
              codeAction.value = `data:image/png;base64,${resData.data.img}`; //  接收为base64的图片要在头部加上data:image/png;base64,
            }
          }
        })
        .catch((error: any) => {
          // 因为服务端登录失败会返回401的http状态码，所以要手动处理
          loadingButton.value = false;
          // console.log('error submit!', fields);
        });
    } else {
      //如果验证失败
    }
  });
};
</script>
<style scoped>
.login {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100vw;
  height: 100vh;
  background-image: url(../assets/image/loginBg.png);
  background-size: 100% 100%;
  background-position: center;
  /* background-size: cover; */
}
.loginForm {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9;
}
/*设置表单样式*/
.loginForm .login-container {
  border-radius: 15px;
  background-clip: padding-box; /*背景绘制在衬距方框内（剪切成衬距方框）。*/
  width: 350px;
  padding: 35px 35px 15px 35px;
  color: #fff;
}

/*官网文档推荐使用:deep(.class) 方式来实现穿透，如果是使用::v-deep会弹出警告信息*/
/* ::v-deep .login-container .el-form-item__label {
  color: #fff;
} */
:deep(.login-container .el-form-item__label) {
  color: #fff;
}
.el-button {
  width: 140px;
  background-color: rgba(25, 1, 255, 0.5);
  border: 0;
}
.loginForm img {
  width: 116%;
  height: 136%;
  position: absolute;
  top: -60px;
  left: -35px;
  z-index: -1;
}
.login_title {
  font-size: 22px;
  font-weight: 400;
  letter-spacing: 2px;
  margin: 0px auto 40px auto;
  text-align: center;
  color: #fff;
}
/* 验证码图片加载失败后的样式 */
.el-image-error-slot {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 80px;
  height: 100%;
  background: #909399;
  font-size: 30px;
}
</style>
